home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / c / c-tools-.000 / c-tools- / c-tools-0.4 / highlight.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-13  |  5.7 KB  |  251 lines

  1. /* highlight.c -- Highlight C source with colors.
  2.    Copyright (C) 1995 Sandro Sigala - <sansig@freenet.hut.fi> */
  3.  
  4. /* $Id: highlight.c,v 1.32 1995/08/08 12:28:25 sandro Exp $ */
  5.  
  6. /* This program is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2 of the License, or
  9.    (at your option) any later version.
  10.  
  11.    This program is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with this program; if not, write to the Free Software
  18.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24.  
  25. #include <getopt.h>
  26.  
  27. #include "lex.h"
  28. #include "misc.h"
  29.  
  30. #include "version.h"
  31.  
  32. FILE *input_file;
  33. FILE *output_file;
  34.  
  35. enum {
  36.     UNBINDED = LEX_LAST_TOKEN + 1,
  37.     NEWLINE, HORIZONTAL_TAB, VERTICAL_TAB, FORM_FEED, CARRIAGE_RETURN
  38. };
  39.  
  40. #include "highlight.h"
  41.  
  42. #define TABLE_SIZE 512
  43.  
  44. static struct { int fg, bg; char *escape; } color_table[TABLE_SIZE];
  45.  
  46. static int last_token = 0;
  47.  
  48. static void
  49. color_table_set_color (int token, int fg, int bg)
  50. {
  51.     char buf[128];
  52.  
  53.     if (color_table[token].escape != NULL)
  54.     free (color_table[token].escape);
  55.  
  56.     color_table[token].fg = fg;
  57.     color_table[token].bg = bg;
  58.  
  59.     sprintf (buf, "\033[%dm", fg);
  60.     if (bg != COLOR_UNCHANGED)
  61.     sprintf (&buf[strlen (buf) - 1], ";%dm", bg);
  62.  
  63.     color_table[token].escape = (char *) xmalloc (strlen (buf) + 1);
  64.     strcpy (color_table[token].escape, buf);
  65. }
  66.  
  67. static void
  68. color_table_free (void)
  69. {
  70.     int i;
  71.     for (i = 0; i < TABLE_SIZE; i++)
  72.     if (color_table[i].escape != NULL)
  73.         free (color_table[i].escape);
  74. }
  75.  
  76. static void
  77. color_table_init (void)
  78. {
  79.     int i;
  80.     for (i = 0; i < TABLE_SIZE; i++)
  81.     { 
  82.     color_table[i].fg = 0;
  83.     color_table[i].bg = 0;
  84.     color_table[i].escape = NULL;
  85.     }
  86. }
  87.  
  88. static void
  89. color_table_setup (void)
  90. {
  91.     int i = 0;
  92.  
  93.     while (def_color_table[i].token != -1)
  94.     {
  95.     color_table_set_color (def_color_table[i].token,
  96.                    def_color_table[i].fg,
  97.                    def_color_table[i].bg);
  98.     i++;
  99.     }
  100. }
  101.  
  102. static void
  103. outstr (char *s)
  104. {
  105.     while (*s)
  106.     fputc (*s++, output_file);
  107. }
  108.  
  109. static void
  110. parse (void)
  111. {
  112.     int tk;
  113.     while ((tk = gettoken ()) != EOF)
  114.     {
  115.     if (color_table[tk].escape != NULL)
  116.     {
  117.         if (color_table[tk].fg != color_table[last_token].fg ||
  118.         color_table[tk].bg != color_table[last_token].bg)
  119.         outstr (color_table[tk].escape);
  120.     }
  121.     else
  122.         outstr (color_table[UNBINDED].escape);
  123.  
  124.     switch (tk)
  125.     {
  126.     case IDENTIFIER: case NUMBER:
  127.     case COMMENT: case DIRECTIVE: case STRING: case CHARACTER:
  128.     case KW_AUTO: case KW_BREAK: case KW_CASE: case KW_CHAR:
  129.     case KW_CONST: case KW_CONTINUE: case KW_DEFAULT: case KW_DO:
  130.     case KW_DOUBLE: case KW_ELSE: case KW_ENUM: case KW_EXTERN:
  131.     case KW_FLOAT: case KW_FOR: case KW_GOTO: case KW_IF:
  132.     case KW_INT: case KW_LONG: case KW_REGISTER: case KW_RETURN:
  133.     case KW_SHORT: case KW_SIGNED: case KW_SIZEOF: case KW_STATIC:
  134.     case KW_STRUCT: case KW_SWITCH: case KW_TYPEDEF: case KW_UNION:
  135.     case KW_UNSIGNED: case KW_VOID: case KW_VOLATILE: case KW_WHILE:
  136.         outstr (lex_token_buffer);
  137.         break;
  138.  
  139.     case TK_DECREMENT: outstr ("--"); break;
  140.     case TK_INCREMENT: outstr ("++"); break;
  141.     case TK_ADD_ASSIGN: outstr ("+="); break;
  142.     case TK_SUB_ASSIGN: outstr ("-="); break;
  143.     case TK_MUL_ASSIGN: outstr ("*="); break;
  144.     case TK_DIV_ASSIGN: outstr ("/="); break;
  145.     case TK_MOD_ASSIGN: outstr ("%="); break;
  146.     case TK_AND_ASSIGN: outstr ("&="); break;
  147.     case TK_OR_ASSIGN: outstr ("|="); break;
  148.     case TK_XOR_ASSIGN: outstr ("^="); break;
  149.     case TK_LEFT_ASSIGN: outstr ("<<="); break;
  150.     case TK_RIGHT_ASSIGN: outstr (">>="); break;
  151.     case TK_PTR_OP: outstr ("->"); break;
  152.     case TK_EQ_OP: outstr ("=="); break;
  153.     case TK_NE_OP: outstr ("!="); break;
  154.     case TK_AND_OP: outstr ("&&"); break;
  155.     case TK_OR_OP: outstr ("||"); break;
  156.     case TK_GE_OP: outstr (">="); break;
  157.     case TK_LE_OP: outstr ("<="); break;
  158.     case TK_LEFT_OP: outstr ("<<"); break;
  159.     case TK_RIGHT_OP: outstr (">>"); break;
  160.     case TK_ELLIPSIS: outstr ("..."); break;
  161.  
  162.     default:
  163.         putc (tk, output_file);
  164.     }
  165.     last_token = tk;
  166.     }
  167. }
  168.  
  169. static void
  170. helppage (char *progname)
  171. {
  172.     fprintf (stderr, "\
  173. %s %s - c-tools %s - Copyright (C) 1995 Sandro Sigala.\n\
  174. usage: %s [-hd] [input [output]]\n\
  175.        -h        display this help and exit\n\
  176.        -d        tread directives as single characters\n\
  177. ", progname, VERSION_HIGHLIGHT, VERSION_CTOOLS, progname);
  178.     exit (0);
  179. }
  180.  
  181. int
  182. main (int argc, char *argv[])
  183. {
  184.     int c;
  185.  
  186.     lex_return_white_spaces = 1;
  187.     lex_return_directives = 1;
  188.  
  189.     while (1)
  190.     {
  191.     c = getopt (argc, argv, "hd");
  192.     if (c == EOF)
  193.         break;
  194.  
  195.     switch (c)
  196.     {
  197.     case 'd':
  198.         lex_return_directives = 0;
  199.         break;
  200.  
  201.     case 'h':
  202.     case '?':
  203.         helppage (argv[0]);
  204.         break;
  205.     }
  206.     }
  207.  
  208.     input_file = stdin;
  209.     output_file = stdout;
  210.  
  211.     if (optind < argc)
  212.     {
  213.     if ((argc - optind) > 2)
  214.         helppage (argv[0]);
  215.  
  216.     if (strcmp (argv[optind], "-") != 0)
  217.         input_file = fopen (argv[optind], "r");
  218.  
  219.     if ((argc - optind) > 1)
  220.         if (strcmp (argv[optind + 1], "-") != 0)
  221.         output_file = fopen (argv[optind + 1], "w");
  222.     }
  223.  
  224.     if (input_file == NULL)
  225.     {
  226.     fprintf (stderr, "%s: cannot open input file\n", argv[0]);
  227.     exit (1);
  228.     }
  229.  
  230.     if (output_file == NULL)
  231.     {
  232.     fprintf (stderr, "%s: cannot open output file\n", argv[0]);
  233.     exit (1);
  234.     }
  235.  
  236.     init_lex ();
  237.  
  238.     color_table_init ();
  239.     color_table_setup ();
  240.  
  241.     parse ();
  242.  
  243.     color_table_free ();
  244.  
  245.     done_lex ();
  246.  
  247.     return 0;
  248. }
  249.  
  250. /* highlight.c ends here */
  251.